package main

import (
	"fmt"
	"log"
	"time"

	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/net"
)

// 计算两个时间点之间的网络IO差异
func calculateDiff(prev, curr net.IOCountersStat) (sent, recv uint64) {
	sent = curr.BytesSent - prev.BytesSent
	recv = curr.BytesRecv - prev.BytesRecv
	return
}

// 格式化字节数为人类可读的单位
func formatBytes(bytes uint64) string {
	const (
		KB = 1 << 10
		MB = 1 << 20
		GB = 1 << 30
	)

	switch {
	case bytes >= GB:
		return fmt.Sprintf("%.2f GB", float64(bytes)/GB)
	case bytes >= MB:
		return fmt.Sprintf("%.2f MB", float64(bytes)/MB)
	case bytes >= KB:
		return fmt.Sprintf("%.2f KB", float64(bytes)/KB)
	default:
		return fmt.Sprintf("%d B", bytes)
	}
}

func main() {

	pts, _ := disk.Partitions(false)
	for _, item := range pts {

		usage, _ := disk.Usage(item.Mountpoint)
		log.Println(item, usage)
	}

	// 获取初始网络IO统计
	prevStats, err := net.IOCounters(true) // 参数true表示获取每个接口的详细信息
	if err != nil {
		fmt.Printf("获取网络统计失败: %v\n", err)
		return
	}

	// 构建接口名到统计信息的映射，方便后续查找
	prevMap := make(map[string]net.IOCountersStat)
	for _, stat := range prevStats {
		prevMap[stat.Name] = stat
	}

	fmt.Println("开始监控网络IO (按Ctrl+C退出)...")
	fmt.Println("接口名\t发送速率\t接收速率\t发送错误\t接收错误")

	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		// 获取当前网络IO统计
		currStats, err := net.IOCounters(true)
		if err != nil {
			fmt.Printf("获取网络统计失败: %v\n", err)
			continue
		}

		// 计算并打印每个接口的IO变化
		for _, curr := range currStats {
			prev, exists := prevMap[curr.Name]
			if !exists {
				continue // 跳过新出现的接口
			}

			// 计算1秒内的发送和接收字节数
			sent, recv := calculateDiff(prev, curr)

			// 打印统计信息
			fmt.Printf(
				"%s\t%s/s\t%s/s\t%d\t%d\n",
				curr.Name,
				formatBytes(sent),
				formatBytes(recv),
				curr.Errout-prev.Errout, // 1秒内新增的发送错误
				curr.Errin-prev.Errin,   // 1秒内新增的接收错误
			)

			// 更新前一次的统计值
			prevMap[curr.Name] = curr
		}

		fmt.Println("----------------------------------------")
	}
}
